package com.bcqn.service.impl;

import com.bcqn.dao.ForumFollowMapper;
import com.bcqn.dao.ForumMapper;
import com.bcqn.dao.ForumTypeMapper;
import com.bcqn.model.ForumFollow;
import com.bcqn.service.ForumService;
import com.bcqn.vo.ForumQueryVo;
import com.bcqn.vo.ForumTypeQueryVo;
import com.bcqn.vo.ForumTypeVo;
import com.bcqn.vo.ForumVo;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * ForumServiceImpl
 *
 * @author Kelly
 * @version v1.0
 * @date 2020/4/17 21:29
 */
@Service
@Slf4j
public class ForumServiceImpl implements ForumService {

    @Autowired
    private ForumMapper forumMapper;

    @Autowired
    private ForumTypeMapper forumTypeMapper;

    @Autowired
    private ForumFollowMapper forumFollowMapper;

    @Override
    public List<ForumVo> getList(Long userId, Integer limitNo) {
        // 用户关注的圈子，为了根据权重排序
        List<ForumVo> followForumList = forumMapper.getFollowForumByUserId(userId);
        // 所有圈子
        List<ForumVo> forumList = forumMapper.getForumList(new ForumQueryVo());

        // 去差集
        List<ForumVo> removeList = removeOrAddList(forumList,followForumList,"0");
        // 取并集
        List<ForumVo> addList = removeOrAddList(followForumList,removeList,"1");


        // 根据用户的id查询用户关注的圈子id
        List<Long> likeForumId = forumMapper.getlikeForumIdByUserId(userId);
        for (ForumVo forumVo :addList){
            //判断查询出来的圈子用户是否关注，如果有则设成true
            if (likeForumId.contains(forumVo.getId())){
                forumVo.setIsFavor(true);
            }
        }

        if (limitNo != null) {
            return addList.subList(0,limitNo);
        }
        return addList;
    }


    @Override
    public List<ForumTypeVo> getListOrderByType(Long userId) {
        // 根据用户的id查询用户关注的圈子id
        List<Long> likeForumId = forumMapper.getlikeForumIdByUserId(userId);

        List<ForumTypeVo> forumTypeVos = forumTypeMapper.getList(new ForumTypeQueryVo());
        for (ForumTypeVo ftv:forumTypeVos) {
            ForumQueryVo fqv = new ForumQueryVo();
            fqv.setTypeId(ftv.getId());
            List<ForumVo> ForumVos =  forumMapper.getForumList(fqv);

            for (ForumVo forumVo :ForumVos){
                //判断查询出来的圈子用户是否关注，如果有则设成true
                if (likeForumId.contains(forumVo.getId())){
                    forumVo.setIsFavor(true);
                }
            }
            ftv.setForumList(ForumVos);
        }
        return forumTypeVos;
    }

    @Override
    public PageInfo<ForumVo> getListByTypeId(ForumQueryVo forumQueryVo) {
        // 根据用户的id查询用户关注的圈子id
        List<Long> likeForumId = forumMapper.getlikeForumIdByUserId(forumQueryVo.getUserId());
        PageHelper.startPage(forumQueryVo.getPageNum(), forumQueryVo.getPageSize());
        ForumQueryVo fqv = new ForumQueryVo();
        fqv.setTypeId(forumQueryVo.getTypeId());
        List<ForumVo> forumVoList = forumMapper.getForumList(fqv);
        for (ForumVo forumVo :forumVoList){
            //判断查询出来的圈子用户是否关注，如果有则设成true
            if (likeForumId.contains(forumVo.getId())){
                forumVo.setIsFavor(true);
            }
        }
        PageInfo<ForumVo> pageInfo = new PageInfo<>(forumVoList);
        return pageInfo;
    }

    @Override
    public int updateForumFollow(ForumFollow forumFollow) {
        ForumFollow ff = forumFollowMapper.selectForumFollow(forumFollow);
        int result;
        if (ff != null) {
            forumFollow.setId(ff.getId());
            result = forumFollowMapper.updateByPrimaryKey(forumFollow);
        } else {
            result = forumFollowMapper.insert(forumFollow);
        }
        return result;
    }

    /**
     * 差集：删除左边集合中在右边集合存在的元素并返回
     * 并集：左边集合加右边集合
     * @param left
     * @param right
     * @return
     */
    private static List<ForumVo> removeOrAddList(List<ForumVo> left, List<ForumVo> right, String type){
        // TODO 改造=泛型集合
        if (left == null){
            return null;
        }
        if (right == null){
            return left;
        }
        //使用LinkedList方便插入和删除
        List<ForumVo> leftList = new LinkedList<>(left);
        List<ForumVo> rightList = new LinkedList<>(right);
        Set<Long> set = new HashSet<>();
        if ("0".equals(type)) {
            // remove 时候将right集合id放入set中
            for(ForumVo item : right){
                set.add(item.getId());
            }
            //迭代器遍历listA
            ListIterator<ForumVo> iter = leftList.listIterator();
            while(iter.hasNext()){
                ForumVo item = iter.next();
                //如果set中包含id则remove
                if(set.contains(item.getId())){
                    iter.remove();
                }
            }
        } else {
            // add 时候将right集合id放入set中
            for(ForumVo item : left){
                set.add(item.getId());
            }
            //迭代器遍历listA
            ListIterator<ForumVo> iter = rightList.listIterator();
            while(iter.hasNext()){
                ForumVo item = iter.next();
                //如果set中包含id则remove
                if(!set.contains(item.getId())){
                    leftList.add(item);
                }
            }
        }
        return leftList;
    }
}
